package com.gmall.product.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gmall.common.result.Result;
import com.gmall.model.product.SpuImage;
import com.gmall.model.product.SpuInfo;
import com.gmall.model.product.SpuPoster;
import com.gmall.product.annotation.MyTransactional;
import com.gmall.product.mapper.SpuImageMapper;
import com.gmall.product.mapper.SpuInfoMapper;
import com.gmall.product.mapper.SpuPosterMapper;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class SpuService
{
    @Autowired
    SpuInfoMapper spuInfoMapper;

    @Autowired
    SpuImageMapper spuImageMapper;

    @Autowired
    SpuPosterMapper spuPosterMapper;
    public Result<IPage<SpuInfo>> getSpuInfoPageByCategory3Id(Integer pageNo, Integer pageSize, Map searchMap) {

        IPage<SpuInfo> page = new Page<>(pageNo, pageSize);
        page.setCurrent(pageNo);
        page.setSize(pageSize);

        QueryWrapper<SpuInfo> queryWrapper = new QueryWrapper<>();;
        if(searchMap.get("category3Id")!=null) {
            queryWrapper.lambda().eq(SpuInfo::getCategory3Id, searchMap.get("category3Id"));
        }
        IPage<SpuInfo> spuInfoIPage = spuInfoMapper.selectPage(page, queryWrapper);

        return Result.ok(spuInfoIPage);
    }

    @MyTransactional
    public Result<String> testAopTransaction(){
        System.out.println("=========testAopTransaction");
        return Result.ok();
    }

    public static void main(String[] args) {
        Integer a = 126;
        Integer b = 126;
        System.out.println(a==b);
    }
    /**
     * ACID  声明式事务  编程式事务
     * Atomic - 原子性  要么一起成功，要么一起失败
     * Consistent - 一致性    业务保证
     * Isolated - 隔离性    解决两个事务同时操作一条记录，或者记录集  出现的问题
     *             脏读：一个事务读取到另一个事务未提交的数据
     *            不可重复读：一个事务先后读取到一条记录，两次读取的数据不一样
     *            幻读：一个事务按照条件查询数据，发现满足条件的记录比之前查询记录多
     * Durable - 持久性    事务没有提交，保存到undo-log中
     * @param spuInfo
     * @return
     */
    //Transactional 什么时候回滚：默认抛出RuntimeExecption
    @Transactional(/*timeout = 2000,readOnly = false,
            rollbackFor = {
                NullPointerException.class,GmallGlobalException.class, ArithmeticException.class
            },
            noRollbackFor = {
                RuntimeException.class,ArrayIndexOutOfBoundsException.class
            },
            isolation = Isolation.REPEATABLE_READ*/propagation = Propagation.REQUIRED)
    //@MyTransactional
    public Result<String> saveSpuInfo(SpuInfo spuInfo) {

        SpuService spuService = (SpuService) AopContext.currentProxy();
        spuService.getSpuImageList(null);


        System.out.println("spuInfo Id:" + spuInfo.getId());
        spuInfoMapper.insert(spuInfo);
        System.out.println("spuInfo Id:" + spuInfo.getId());

        //保存图片
        List<SpuImage> spuImageList = spuInfo.getSpuImageList();

        spuImageList.forEach(spuImage -> {
            spuImage.setSpuId(spuInfo.getId());
            spuImageMapper.insert(spuImage);
        });
        //保存海报
        List<SpuPoster> spuPosterList = spuInfo.getSpuPosterList();

        spuPosterList.forEach(spuPoster -> {
            spuPoster.setSpuId(spuInfo.getId());
            spuPosterMapper.insert(spuPoster);
        });
        return Result.ok();
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public Result<List<SpuImage>> getSpuImageList(Long spuId) {


        //select * from spu_image where spu_id = #{spuId}
        QueryWrapper<SpuImage> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SpuImage::getSpuId, spuId);
        List<SpuImage> spuImages = spuImageMapper.selectList(queryWrapper);
        return Result.ok(spuImages);
    }
}
